React基础

相关资料

  1. 官方文档: https://react.docschina.org/

  2. demo练习: git@gitee.com:huruqing/react-demos-template.git

  3. villa 项目模板: git@gitee.com:huruqing/villa-react-template.git

  4. vscode插件:

    1. Prettier - Code formatter 格式化插件
    2. jsx-beautify 格式化插件 快捷键ctrl+m
    3. Simple React Snippets 片段插件
  5. react 片段插件

    • imr 导入react
    • imrc 导入react和Component
    • cc 类组件
    • ccc 带Constructor的类组件
    • imrs 导入useState
    • imrse 导入useEffect
    • ren 渲染函数render
    • ffc 函数组件
    • cdm componentDidMount生命周期
    • ss setState
    • impc PureComponent

(一) react组件

(1) es5组件(函数组件)

一个函数就是一个组件, 这个函数需要有一个return()

import React from 'react';

export default function() {
    return(
        <div>
            <h4>es5组件</h4>
            <p>
                hello react
            </p>
        </div>
    );
}

(2) react组件es6 (类组件)

  1. 需要提供constructor并执行super()
  2. 需要提供一个render方法
import React from 'react';

class Demo extends React.Component{
    constructor() {
        super();
    }

    // 需要提供一个render方法
    render() {
        return (
            <div>
                <h4>es6 组件</h4>
                <p>
                    hello react
                </p>
            </div>
        )
    }
}

export default Demo;

(二) react静态页面

import React from 'react'; 

export default function() {
    return(
        <div>
            <h4>静态页面</h4>
            <div className="box" style={{border:'1px solid',color:'red'}}>
                阿斯顿发是的发送到发斯蒂芬阿瑟发斯蒂芬
            </div>
        </div>
    )
}

(三) react生命周期

import React, { Component } from "react";

class Demo extends Component {
  constructor() {
    super();
  }

  render() {
      return <div>生命周期函数</div>
  }

  componentWillMount() {
    console.log("组件将要挂载");
  }

  // 发请求在此生命周期
  componentDidMount() {
    console.log("组件已经挂载");
  }
  componentWillReceiveProps(newProps) {
    console.log("组件将接收属性数据");
  }
  shouldComponentUpdate(nextProps, nextState) {
    // 此生命周期用来优化性能
    return true;
  }
  componentWillUpdate(nextProps, nextState) {
    console.log("组件将要更新");
  }
  componentDidUpdate(prevProps, prevState) {
    console.log("组件已经更新完毕");
  }
  componentWillUnmount() {
    console.log("组件将要卸载");
  }
}

export default Demo;

(四) jsx语法和注释

jsx语法规范:

  1. 遇到<>, 看做html(标签)来进行解析
  2. 遇到{}, 看做是js来进行解析
  3. 注释{/* */}
import React from 'react';

export default function() {
    let person = {
        username:'法外狂徒',
        page: 100
    } 
   
    return(
        <div>
            <p>姓名: {person.username}</p>
            <p>年龄: {person.age}</p>
        </div>
    )
}

(五) 事件绑定

(1) 事件绑定demo (类组件)

  1. 点击事件写成 onClick={}
  2. 注意this的指向
import React from "react";

class Demo extends React.Component {
  constructor() {
    super();
    // 让test函数的this永远指向Demo实例
    this.test = this.test.bind(this); 
  }
    
  test2 = ()=> {
      console.log(this); // 使用箭头函数, this也不会丢失
  }  

  test() { 
    alert("哈哈哈哈哈哈哈");
  } 

  render() {
    return (
      <div>
        <button onClick={this.test}>点我啊</button>
      </div>
    );
  }
}

export default Demo;

(2) 函数组件绑定事件

import React from "react";

function Demo() {
  const handleClick = () => {
    console.log(22222);
  };

  return <button onClick={handleClick}>点击</button>;
}
export default Demo;

(3) 事件传参

// 类组件
import React from 'react';

class Demo extends React.Component{
    constructor() {
        super();
        this.test = this.test.bind(this);
    }

    test(data) {
        console.log(data);
    }

    render() {
        return(
            <div>
                <button onClick={()=>{this.test('111')}}>张三</button>
                <button onClick={()=>{this.test('222')}}>李四</button>
                <button onClick={()=>{this.test('333')}}>王五</button>
            </div>
        )
    }
}

export default Demo;


// 函数组件
import React from "react";

function Demo() {
  const handleClick = (index) => {
    alert(index);
  };

  return (
    <div>
      <button onClick={()=> {handleClick(1)}}>点击1</button>
      <button onClick={()=> {handleClick(2)}}>点击2</button>
      <button onClick={()=> {handleClick(3)}}>点击3</button>
    </div>
  );
}

export default Demo;

(六) 列表渲染

import React from 'react';

class Demo extends React.Component{
    constructor() {
        super();
    }

    render() {
        let list = [
            {username:'zs1',age:20,id:"01"},
            {username:'zs2',age:21,id:"02"},
            {username:'zs3',age:22,id:"03"},
            {username:'zs4',age:23,id:"04"},
        ]

        return(
            <ul>
               {
                   list.map((item,index)=> {
                       return (
                        <li key={item.id}>
                            {index+1}. <span>用户名: {item.username}</span> <span>年龄: {item.age}</span>
                        </li>
                       )
                   })
               }
            </ul>
        )
    }
}

export default Demo;

(七) 条件渲染

import React from 'react';

export default function() {
    let isLogin = true; 
    return (
        <div>
            <h4>条件渲染</h4> 
            { isLogin? <p>138****0000</p>:
      				<p>还没登录,<button>立即登录</button></p>  
      			} 
        </div>
    )
}

(八) state和setState

(1) state和setState的demo

  1. state 定义状态
  2. setState 修改状态
import React from 'react';

class Demo extends React.Component{
    constructor() {
        super();
        this.state = {
            isLogin: false
        }
        this.login = this.login.bind(this);
    }

    login() {
        // 修改state里的状态
        this.setState({
            isLogin: true
        });
    }

    render() {
        console.log('执行render方法');
        let {isLogin} = this.state;
        return (
            <div>
                <h4>条件渲染</h4> 
                { isLogin? <p>138****0000</p>:<p>还没登录,<button onClick={this.login}>立即登录</button></p>  } 
            </div>
        )
    }
}

export default Demo;

(2) state和性能优化

  1. 只要执行setState, render函数默认会执行
  2. 使用shouldUpdateComponent进行性能优化, 只有当状态发生改变的时候在执行render函数
import React from 'react';

class Demo extends React.Component{
    constructor() {
        super();
        this.state = {
            show: false
        }
        this.change1 = this.change1.bind(this);
        this.change2 = this.change2.bind(this);
    }

    change1() {
        // 修改state里的状态
        this.setState({
            show: !this.state.show
        });
    } 

    change2() {
        // 修改state里的状态
        this.setState({
            show: true
        });
    } 
    /**
     * 优化性能
     * @param {*} nextProps 下一个属性(新属性), nextState 
     * @param {*} nextState 下一个state(新的状态)
     * @returns 
     */ 
    shouldComponentUpdate(nextProps, nextState) { 
        // 新的状态和旧的状态的值相同时, 不重新渲染页面
        if (this.state.show === nextState.show) {
          // 返回false不重新渲染页面
            return false;
        } else {
          // 返回true重新渲染页面
            return true;
        } 
      }

    render() { 
        console.log('重新渲染')
        let {show} = this.state;
        return (
            <div>
                <h4>state和render</h4>
                <p>
                    <button onClick={this.change1}>btn1</button>
                    <button onClick={this.change2}>btn2</button>
                </p>
                {
                   show? <div>
                   <p>sdfasdfasdfasdfasdfasdfasdf</p>
                   <p>sdfasdfasdfasdfasdfasdfasdf</p>
                   <p>sdfasdfasdfasdfasdfasdfasdf</p>
               </div>:'' 
                } 
            </div>
        )
    }
}

export default Demo;

(九) 表单输入

(1) 单个输入框

通过setState来显示用户的输入

import React from 'react';

class Demo extends React.Component{
    constructor() {
        super();
        this.state = {
            username: ''
        }
        this.changeUsername = this.changeUsername.bind(this);
    }

    changeUsername() { 
        this.setState({
            username: event.target.value
        })
    }

    render() {
        return(
            <div>
                <h4>表单输入</h4>
                <input type="text" value={this.state.username} onChange={this.changeUsername}/>
            </div>
        )
    }
}

export default Demo;

(2)多个输入框

import React from 'react';

class Demo extends React.Component{
    constructor() {
        super();
        this.state = {
            username: '',
            password:''
        }
        this.change = this.change.bind(this);
    }

    change() { 
        // 获取输入的dom节点
        let target = event.target;
        // input标签上定义的name的值
        let name = target.name; 
        this.setState({ 
           [name]: target.value
        })
    }

    render() {
        return(
            <div>
                <h4>表单输入</h4>
                <input placeholder="用户名" type="text" name="username" value={this.state.username} 
  onChange={this.change}/>
                <input placeholder="密码" type="text" name="password" value={this.state.password} 
onChange={this.change}/>
            </div>
        )
    }
}

export default Demo;

(3) 受控组件和不受控组件

  1. 普通的input标签是不受控组件, 因为用户想输入什么就输入什么
  2. 在react里,我们对input标签的输入和事件等都进行了控制, 所以就变成了受控组件

(九) 获取真实的 DOM 节点

import React, { Component } from "react";

class Demo extends Component {
  constructor(props) {
    super(props);
    // 创建一个ref
    this.myInput = React.createRef();
  }

  // 组件挂载完毕之后使用输入框获得焦点
  componentDidMount() {
    this.myInput.current.focus();
  }

  render() {
    return (
      <div>
        <input ref={this.myInput} />
      </div>
    );
  }
}

export default Demo;

(十) 父子组件通信

(1) 父传子

  1. 父组件通过属性把数据传给子组件
  2. 类组件通过 this.props 接收数据
  3. 函数组件通过参数 props 接收数据
// 父组件
import React, { Component } from "react";
import Demo1 from "./demos/Demo1";
import Demo2 from "./demos/Demo2";

class Demo extends Component {
  constructor(props) {
    super(props);
    this.state = {
      username: "张三",
    };
  }
  render() {
    return (
      <div>
        <h3>父组件</h3>
        <hr/>
        {/* 给大儿子(类组件)传字符串属性 */}
        <Demo1 msg="hello, 大儿子"/>
        {/* 给二儿子(函数组件)传参变量属性 */}
        <Demo2 username={this.state.username}/>
      </div>
    );
  }
}

export default Demo;

// 子组件(类) 
import React, { Component } from 'react';

class Demo1 extends Component {
  constructor(props) {
    super(props); 
  } 
  render() { 
    return ( 
      <div>
        <h4>大儿子</h4>
        <p>{this.props.msg}</p>
      </div>
     );
  }
}
 
export default Demo1;

// 子组件(函数)
import React from "react";

function Demo(props) {
  return (
    <div>
      <h4>二儿子</h4>
      <p>{props.username}</p>
    </div>
    
  );
} 
export default Demo;

(2) 子传父

  1. 父组件给子组件通过属性的传一个函数

  2. 字组件调用这个函数并传入数据

    // 父组件
    import React, { Component } from "react";
    import Demo1 from "./demos/Demo1"; 
    
    class Demo extends Component {
      constructor(props) {
        super(props); 
      } 
      // 1. 声明一个函数用来接收数据
      getData(data) {
        console.log(data);
      } 
    
      render() {
        return (
          <div>
            <h3>父组件</h3> 
            {/* 2.将函数以属性的方式传给子组件 */}
            <Demo1 getData={this.getData}/> 
          </div>
        );
      }
    } 
    export default Demo;
    
    // 子组件 
    import React, { Component } from 'react';
    
    class Demo1 extends Component {
      constructor(props) {
        super(props); 
      }  
    
      render() { 
        return ( 
          <div>  
            <span>子组件</span> <button onClick={()=> {this.props.getData({name:'zs',age:18})}}>发送数据</button>
          </div>
         );
      }
    }
     
    export default Demo1;